package com.cocos.game;

import android.app.Activity;
import android.content.Context;
import android.util.Log;


import com.cocos.game.param.TapTapInitParam;
import com.cocos.game.result.LoginInfo;
import com.cocos.game.result.LoginResult;
import com.cocos.game.result.RemainingTimeResult;
import com.cocos.lib.JsbBridge;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.taptap.sdk.compilance.TapTapCompliance;
import com.taptap.sdk.compilance.TapTapComplianceCallback;
import com.taptap.sdk.compilance.constants.ComplianceMessage;
import com.taptap.sdk.compilance.option.TapTapComplianceOptions;
import com.taptap.sdk.core.TapTapRegion;
import com.taptap.sdk.core.TapTapSdk;
import com.taptap.sdk.core.TapTapSdkOptions;
import com.taptap.sdk.kit.internal.callback.TapTapCallback;
import com.taptap.sdk.kit.internal.exception.TapTapException;
import com.taptap.sdk.login.Scopes;
import com.taptap.sdk.login.TapTapAccount;
import com.taptap.sdk.login.TapTapLogin;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Map;

public class TapTapSingle {
    // adb.exe connect 127.0.0.1:7555 链接MuMu模拟器
    //当前SDK是否已经初始化
    private boolean initFlag = false;

    private TapTapInitParam tapInitParam = new TapTapInitParam();

    //当前上下文
    private Activity activity = null;

    private final Gson gson;

    // 私有构造函数，防止外部实例化
    private TapTapSingle() {
        // 可以在这里执行一些初始化操作

        // 创建 GsonBuilder 实例并注册自定义序列化器
        GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapter(ResultCodeEnum.class, new ResultCodeEnumSerializer());

        // 创建 Gson 实例
        gson = builder.create();
    }

    /**
     * 设置游戏Activity 初始化这些都要用到
     *
     * @param activity 当前上下文
     */
    public void setActivity(Activity activity) {
        this.activity = activity;
    }

    public void onScript(String arg0, String arg1) {

        FuntionEnum f = FuntionEnum.fromString(arg0);

        switch (f) {
            case INIT:
                init(arg1);
                break;
            case LOGIN:
                login();
                break;
            case REMAINING_TIME:
                remainingTime();
                break;
            case PLAY_AD:
                break;
            default:
                break;
        }
    }

    /************************************************************************
     * SDK 相关方法封装
     ***********************************************************************/
    //获取玩家剩余游戏时间(秒) 成年人获取时，时间为9999
    private void remainingTime() {
        int remainingTime = TapTapCompliance.getRemainingTime(); // 单位:秒
        RemainingTimeResult result = new RemainingTimeResult();
        result.setCode(ResultCodeEnum.SUCCESS);
        result.setMessage("获取成功");
        result.setData(remainingTime);

        String string = gson.toJson(result);

        sendToScript(FuntionEnum.REMAINING_TIME_BACK.getName(), string);
    }


    private void init(String json) {
        //{"clientId":"go9tdy1bmosuhp6kyx","clientToken":"IJwnIJECJGnW3w3X8dl5zWO1KZBleWZTfDynlfml","enableLog":false,"showSwitchAccount":true,"useAgeRange":true}
        tapInitParam = gson.fromJson(json, TapTapInitParam.class);
    }

    // 静态方法示例
    private void initSDK(Context context) {

        String json = gson.toJson(tapInitParam);

        TapTapSdkOptions tapSdkOptions = new TapTapSdkOptions(tapInitParam.getClientId(), // 游戏 Client ID
                tapInitParam.getClientToken(), // 游戏 Client Token
                TapTapRegion.CN // 游戏可玩区域: [TapTapRegion.CN]=国内 [TapTapRegion.GLOBAL]=海外
        );

        // 是否开启 log，建议 Debug 开启，Release 关闭，默认关闭 log
        boolean enableLog = tapInitParam.getEnableLog();

        tapSdkOptions.setEnableLog(enableLog);

        // 可选配置 合规模块
        TapTapComplianceOptions tapComplianceOptions = new TapTapComplianceOptions(tapInitParam.getShowSwitchAccount(), // 是否显示切换账号按钮，默认为 false
                tapInitParam.getUseAgeRange() // 游戏是否需要获取真实年龄段信息，默认为 true
        );
        // 初始化 TapSDK
        TapTapSdk.init(context, tapSdkOptions, tapComplianceOptions);

        TapTapCompliance.registerComplianceCallback(new TapTapComplianceCallback() {
            @Override
            public void onComplianceResult(int code, @Nullable Map<String, ?> extra) {
                // 合规结果
                switch (code) {
                    case ComplianceMessage.LOGIN_SUCCESS://玩家未受到限制，正常进入游戏
                        int ageRange = TapTapCompliance.getAgeRange();
                        TapTapAccount currentTapAccount = TapTapLogin.getCurrentTapAccount();
                        if (currentTapAccount != null) {
                            loginSuccess(currentTapAccount, ageRange);
                        }
                        break;
                    case ComplianceMessage.EXITED://退出防沉迷认证及检查，当开发者调用 Exit 接口时或用户认证信息无效时触发，游戏应返回到登录页
                        TapTapLogin.logout();
                        login();
                        break;
                    case ComplianceMessage.PERIOD_RESTRICT://用户当前时间无法进行游戏，此时用户只能退出游戏或切换账号
                    case ComplianceMessage.DURATION_LIMIT://用户无可玩时长，此时用户只能退出游戏或切换账号
                        // 此时用户只能退出游戏或切换账号 不用做逻辑处理等待用户操作
                        break;
                    case ComplianceMessage.SWITCH_ACCOUNT://用户点击切换账号，游戏应返回到登录页
                        TapTapLogin.logout();
                        login();
                        break;
                    case ComplianceMessage.AGE_LIMIT://当前用户因触发应用设置的年龄限制无法进入游戏
                        loginFail(ResultCodeEnum.AGE_LIMIT, "防沉迷限制");
                        break;
                    case ComplianceMessage.INVALID_CLIENT_OR_NETWORK_ERROR://数据请求失败，游戏需检查当前设置的应用信息是否正确及判断当前网络连接是否正常
                        loginFail(ResultCodeEnum.NETWORK_ERROR, "网络错误");
                        break;
                    case ComplianceMessage.REAL_NAME_STOP://实名过程中点击了关闭实名窗，游戏可重新开始防沉迷认证
//                        startup();
                        TapTapCompliance.exit();
                        break;
                    default:
                        break;
                }
            }
        });
        initFlag = true;
    }

    private void login() {
        login(activity);
    }

    /**
     * 登录
     *
     * @param activity 上下文
     */
    private void login(Activity activity) {
        //判断是否初始化SDK
        if (!initFlag) {
            initSDK(activity);
        }

        TapTapAccount currentTapAccount = TapTapLogin.getCurrentTapAccount();
        if (currentTapAccount != null) {
            startup();
        } else {
            loginWithScopes();
        }

    }

    /**
     * 登录并授权
     */
    private void loginWithScopes() {
        // 定义授权范围
        /**
         * 不同的授权范围
         * TapTap 授权登录接口支持选择不同的授权范围且支持任意组合，但必须包含 public_profile 和 basic_info 中的一个，不然无法获得 openid 和 unionid。
         * TapTap 授权登录接口可以传递 String 类型的数组作为参数，开发者可以根据自己业务需求添加不同的权限为数组的元素。
         * 若游戏发起 TapTap 授权登录时只请求 basic_info 的权限，则用户可享受无感登录的特性，即用户不需要手动确认授权即可自动授权完成登录。
         * 权限	说明
         * public_profile	获得 openid、unionid、用户昵称、用户头像
         * user_friends	获得访问 TapTap 好友相关数据的权限
         * basic_info	获得 openid 和 unionid
         */
        String[] scopes = new String[]{Scopes.SCOPE_BASIC_INFO};

        TapTapLogin.loginWithScopes(activity, scopes, new TapTapCallback<TapTapAccount>() {
            @Override
            public void onSuccess(TapTapAccount tapTapAccount) {
                // 登录成功
                startup();
            }

            @Override
            public void onFail(@NotNull TapTapException exception) {
                // 登录失败
                loginFail(ResultCodeEnum.FAIL, exception.getLocalizedMessage());
            }

            @Override
            public void onCancel() {
                // 登录取消
                loginFail(ResultCodeEnum.CANCEL, "登录取消");
            }
        });
    }

    /**
     * 实名认证
     */
    public void startup() {
        TapTapAccount tapAccount = TapTapLogin.getCurrentTapAccount();
        if (tapAccount != null) {
            String unionId = tapAccount.getUnionId();
            TapTapCompliance.startup(activity, unionId);
        } else {
            // 当前账号信息获取失败,重新登录
            login();
        }
    }

    /************************************************************************
     * 发送数据到JS
     ***********************************************************************/
    /**
     * @param currentTapAccount 当前账号数据
     * @param age               年龄
     */
    private void loginSuccess(TapTapAccount currentTapAccount, int age) {
        LoginInfo info = new LoginInfo();
        info.setAge(age);
        info.setOpenId(currentTapAccount.getOpenId());
        info.setRes(gson.toJson(currentTapAccount));

        LoginResult loginResult = new LoginResult();
        loginResult.setCode(ResultCodeEnum.SUCCESS);
        loginResult.setMessage("登录成功");
        loginResult.setData(info);

        String string = gson.toJson(loginResult);

        sendToScript(FuntionEnum.LOGIN_BACK.getName(), string);
    }

    /**
     * 登录失败
     *
     * @param code 失败状态码
     * @param msg  失败消息
     */
    private void loginFail(ResultCodeEnum code, String msg) {
        LoginResult loginResult = new LoginResult();
        loginResult.setCode(code);
        loginResult.setMessage(msg);

        String string = gson.toJson(loginResult);

        sendToScript(FuntionEnum.LOGIN_BACK.getName(), string);
    }

    private void sendToScript(String arg0, String arg1) {
        JsbBridge.sendToScript(arg0,arg1);
    }

    /************************************************************************
     * 单例
     ***********************************************************************/
    private static final class InstanceHolder {
        // 在类加载时初始化单例对象
        static final TapTapSingle instance = new TapTapSingle();
    }

    // 提供一个全局访问点，返回单例对象
    public static TapTapSingle getInstance() {
        return InstanceHolder.instance;
    }
}
